const getHashValGenerator = () => {
	const hashValMap = new Map();

	return function getHashVal(hash) {
		if (hashValMap.has(hash)) {
			return hashValMap.get(hash)
		} else {
			const hash_val = hashValMap.size + 1;
			hashValMap.set(hash, hash_val);
			return hash_val;
		}
	};
}
const getNumberVal = getHashValGenerator();
const getTypeVal = getHashValGenerator();

const CARD_INSTANCE_CACHE = new Map();
export default class Card {
	static getIns(txt) {
		return CARD_INSTANCE_CACHE.get(txt)
	}
	static buildIns(type, number) {
		const txt = `${type}_${number}`;
		if (CARD_INSTANCE_CACHE.has(txt)) {
			return CARD_INSTANCE_CACHE.get(txt)
		} else {
			const ins = new Card(type, number);
			CARD_INSTANCE_CACHE.set(txt, ins);
			return ins;
		}
	}
	constructor(type, number) {
		this.type = type;
		this.number = number;
		this.is_selected = false;
		this.is_used = false;
		this._type_val = getTypeVal(type);
		this._val = getNumberVal(number);
		this._txt = type + '_' + number;
	}
	reset() {
		this.is_selected = false;
		this.is_used = false;
	}
	valueOfType() {
		return this._type_val;
	}
	valueOf() {
		return this._val;
	}
	toString() {
		return this._txt;
	}
	toJSON() {
		return this._txt;
	}
}

export class CardList extends Array {
	static sort_cards(list) {
		return list.sort((a, b) => a - b)
	};
	static filter_remove_cards(list, remove_list) {
		const remove_map = new WeakMap();
		remove_list.forEach(card => remove_map.set(card, true));
		return list.filter(card => !remove_map.has(card));
	};
	first() {
		return this[0]
	};
	last() {
		return this[this.length - 1]
	};
	sort_cards() {
		return CardList.sort_cards(this)
	};
};
Card.CardList = CardList;

export const CARD_LIST = (() => {
	const list = [];
	const types = "黑桃|红心|梅花|方块".split("|");
	const numbers = "1|2|3|4|5|6|7|8|9|10|J|Q|K".split("|");
	types.forEach(type => numbers.forEach(number => {
		const card = Card.buildIns(type, number);
		list.push(card);
	}));
	return list;
})();
